﻿package com.dbm.util;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;

public class JaxbUtil {

	private JAXBContext jaxbContext;

	public JaxbUtil(Class<?>... types) {
		try {

			jaxbContext = JAXBContext.newInstance(types);

		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Java Object to XML
	 * 
	 * @param root
	 * @param encoding
	 * @return
	 */
	public String toXml(Object root, String encoding) {
		try {
			StringWriter writer = new StringWriter();
			createMarshaller(encoding).marshal(root, writer);
			return writer.toString();
		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Java Object to XML,鏀寔Root Element鏄疌ollection鐨勬儏褰?
	 * 
	 * @param root
	 * @param rootName
	 * @param encoding
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String toXml(Collection root, String rootName, String encoding) {
		try {
			CollectionWrapper wrapper = new CollectionWrapper();
			wrapper.collection = root;

			JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),
					CollectionWrapper.class, wrapper);
			StringWriter writer = new StringWriter();
			createMarshaller(encoding).marshal(wrapperElement, writer);
			return writer.toString();

		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * XML to Java Object
	 * @param xml
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T fromXml(String xml){
		try {
			StringReader reader = new StringReader(xml);
			return (T) createUnmarshaller().unmarshal(reader);
		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * XML to Java Object 锛屾敮鎸佸ぇ灏忓啓鏁忔劅鎴栦笉鏁忔劅
	 * @param xml
	 * @param caseSensitive
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T fromXml(String xml, boolean caseSensitive){
		try {
			String fromXml = xml;
			if(!caseSensitive){
				fromXml = xml.toLowerCase();
			}
			StringReader reader = new StringReader(fromXml);
			return (T) createUnmarshaller().unmarshal(reader);
		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}
	
	// 鍒涘缓Marshaller,璁惧畾encoding锛堝彲涓簄ull锛?
	public Marshaller createMarshaller(String encoding) {
		try {
			Marshaller marshaller = jaxbContext.createMarshaller();

			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

			if (!"".equals(encoding)) {
				marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
			}
			return marshaller;
		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}

	// 鍒涘缓 UnMarshaller
	public Unmarshaller createUnmarshaller() {
		try {
			return jaxbContext.createUnmarshaller();
		} catch (JAXBException e) {
			throw new RuntimeException(e);
		}
	}

	// 灏佽Root Element 鏄?Collection 鐨勬儏鍐?
	public static class CollectionWrapper {
		@SuppressWarnings("unchecked")
		@XmlAnyElement
		protected Collection collection;
	}

}
